﻿/*************************************************************************************
 * 文 件 名:   IHK_TargetCamSystem
 * 
 * 描    述:   HK_TargetCam系统层脚本
 * 
 * 版    本：  V1.1
 * 创 建 者：  京产肠饭
 * 创建时间：  2021/12/8
 * 链   接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using System.Collections.Generic;
using DG.Tweening;
using QFramework;
using UnityEngine;

namespace HKTools
{
    public enum MoveType
    {
        Rot,
        Area,
        Follow
    }

    public interface IHK_TargetCamSystem : ISystem
    {
        /// <summary>
        /// 是否可以控制摄像机
        /// </summary>
        bool IsCanControlCam { get; set; }

        /// <summary>
        /// 当前 控制的 Camera
        /// </summary>
        HK_TargetCamCtrl CtrlCam { get; set; }

        /// <summary>
        /// Camera 切换Target时，运动的时间
        /// </summary>
        float CamGotoTime { get; set; }

        BindableProperty<MoveType> CamMoveType { get; }

        // 相机目标列表
        List<HK_BaseTargetItem> Target_List { get; set; }

        // 当前相机目标
        HK_BaseTargetItem CurTarget { get; set; }

        /// <summary>
        /// 初始化 被控制的 Camera
        /// </summary>
        void InitCamera(HK_TargetCamCtrl camera);

        /// <summary>
        /// 初始化 CamTarget列表
        /// </summary>
        void InitCamTargetList(HK_BaseTargetItem targetItem);

        /// <summary>
        /// 通过 枚举类型 改变 CamTarget
        /// </summary>
        void ChangeTargetByEnum(HK_TargetEnum targetType, float moveSpeed, float wheelSpeed, bool isFlash, bool isBlink);

        /// <summary>
        /// 通过 名字 改变 CamTarget
        /// </summary>
        void ChangeTargetByName(string targetName, float moveSpeed, float wheelSpeed, bool isFlash, bool isBlink);

        /// <summary>
        /// 设置摄像机状态
        /// </summary>
        /// <param name="isCanCtrl"></param>
        void SetCameraState(bool isCanCtrl);
    }

    public class HK_TargetCamSystem : AbstractSystem, IHK_TargetCamSystem
    {
        /// <summary>
        /// 是否可以控制摄像机
        /// </summary>
        public bool IsCanControlCam { get; set; }

        /// <summary>
        /// 当前 控制的 Camera
        /// </summary>
        public HK_TargetCamCtrl CtrlCam { get; set; }

        /// <summary>
        /// Camera 切换Target时，运动的时间
        /// </summary>
        public float CamGotoTime { get; set; }

        public BindableProperty<MoveType> CamMoveType { get; } = new BindableProperty<MoveType>();

        public List<HK_BaseTargetItem> Target_List { get; set; }

        public HK_BaseTargetItem CurTarget { get; set; }

        protected override void OnInit()
        {
            IsCanControlCam = true;

            CamGotoTime = 0.65f;

            Target_List = new List<HK_BaseTargetItem>();

            CamMoveType.Value = MoveType.Rot;
        }

        /// <summary>
        /// 初始化 被控制的 Camera
        /// </summary>
        public void InitCamera(HK_TargetCamCtrl targetCamCtrl)
        {
            this.CtrlCam = targetCamCtrl;
        }

        /// <summary>
        /// 初始化 CamTarget列表
        /// </summary>
        public void InitCamTargetList(HK_BaseTargetItem targetItem)
        {
            Target_List.Add(targetItem);
        }

        /// <summary>
        /// 通过 枚举类型 改变 CamTarget
        /// </summary>
        public void ChangeTargetByEnum(HK_TargetEnum targetType, float moveSpeed, float wheelSpeed, bool isFlash, bool isBlink)
        {
            HK_BaseTargetItem newTarget = null;

            for (int i = 0; i < Target_List.Count; i++)
            {
                if (Target_List[i].targetEnum == targetType)
                    newTarget = Target_List[i];
            }

            if (newTarget == null || newTarget == CurTarget)
            {
                return;
            }

            ChangeTarget(newTarget, moveSpeed, wheelSpeed, isFlash, isBlink);
        }

        /// <summary>
        /// 通过 名字 改变 CamTarget
        /// </summary>
        public void ChangeTargetByName(string targetName, float moveSpeed, float wheelSpeed, bool isFlash, bool isBlink)
        {
            HK_BaseTargetItem newTarget = null;

            for (int i = 0; i < Target_List.Count; i++)
            {
                if (Target_List[i].targetName == targetName)
                    newTarget = Target_List[i];
            }

            if (newTarget == null || newTarget == CurTarget)
            {
                return;
            }

            ChangeTarget(newTarget, moveSpeed, wheelSpeed, isFlash, isBlink);
        }

        float blinkTime = 0.4f;

        void ChangeTarget(HK_BaseTargetItem newTarget, float moveSpeed, float wheelSpeed, bool isFlash, bool isBlink)
        {
            if (isFlash)
            {
                CamGotoTime = 0;
                if (isBlink)
                    blinkTime = 0.4f;
                else
                    blinkTime = 0f;
            }
            else
            {
                CamGotoTime = 0.65f;
                blinkTime = 0f;
            }

            if (blinkTime == 0.4f)
            {
                ActionKit.Sequence()
                    .Callback(() => CtrlCam.ShowMask())
                    .Delay(blinkTime)
                    .Callback(() => ChangeTargetAnim(newTarget, moveSpeed, wheelSpeed))
                    .StartGlobal();
            }
            else
            {
                ChangeTargetAnim(newTarget, moveSpeed, wheelSpeed);
            }
        }

        void ChangeTargetAnim(HK_BaseTargetItem newTarget, float moveSpeed, float wheelSpeed)
        {
            if (CtrlCam.GetComponent<Camera>().fieldOfView != newTarget.FOV)
            {
                CtrlCam.GetComponent<Camera>().DOFieldOfView(newTarget.FOV, CamGotoTime).SetDelay(newTarget.ChangeFOV_Delay);
            }

            // 切换至新的 RotTarget 目标
            if (newTarget is HK_RotTargetItem)
            {
                HK_RotTargetItem targetItem = newTarget as HK_RotTargetItem;

                Quaternion lookAtRot = Quaternion.LookRotation(targetItem.targetDir, targetItem.transform.up);
                Vector3 resultEuler = lookAtRot.eulerAngles;

                CtrlCam.transform.DORotate(resultEuler, CamGotoTime);

                CtrlCam.transform.DOMove(targetItem.targetPos, CamGotoTime)
                    .OnPlay(() =>
                    {
                        // 发送 开始切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetBegin()
                        {
                            _targetEnum = targetItem.targetEnum,
                            _targetName = targetItem.targetName
                        });
                        IsCanControlCam = false;
                    })
                    .OnComplete(() =>
                    {
                        IsCanControlCam = true;

                        // 发送 完成切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetEnd()
                        {
                            _targetEnum = targetItem.targetEnum,
                            _targetName = targetItem.targetName
                        });
                    });

                CurTarget = newTarget;

                this.SendEvent(new Event_SwitchToRotTarget()
                {
                    _rotTargetItem = newTarget as HK_RotTargetItem,
                    _moveSpeed = moveSpeed,
                    _wheelSpeed = wheelSpeed
                });

                CamMoveType.Value = MoveType.Rot;
            }

            // 切换至新的 AreaTarget 目标
            if (newTarget is HK_AreaTargetItem)
            {
                HK_AreaTargetItem targetItem = newTarget as HK_AreaTargetItem;

                Quaternion lookAtRot = Quaternion.LookRotation(targetItem.targetDir);
                Vector3 resultEuler = lookAtRot.eulerAngles;

                CtrlCam.transform.DORotate(resultEuler, CamGotoTime);

                CtrlCam.transform.DOMove(targetItem.targetPos, CamGotoTime)
                    .OnPlay(() =>
                    {
                        // 发送 开始切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetBegin()
                        {
                            _targetEnum = targetItem.targetEnum,
                            _targetName = targetItem.targetName
                        });
                        IsCanControlCam = false;
                    })
                    .OnComplete(() =>
                    {
                        IsCanControlCam = true;

                        // 发送 完成切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetEnd()
                        {
                            _targetEnum = targetItem.targetEnum,
                            _targetName = targetItem.targetName
                        });
                    });

                CurTarget = newTarget;

                this.SendEvent(new Event_SwitchToAreaTarget()
                {
                    _areaTargetItem = newTarget as HK_AreaTargetItem,
                    _moveSpeed = moveSpeed,
                    _wheelSpeed = wheelSpeed
                });

                CamMoveType.Value = MoveType.Area;
            }

            // 切换至新的 FollowTarget 目标
            if (newTarget is HK_FollowTargetItem)
            {
                HK_FollowTargetItem targetItem = newTarget as HK_FollowTargetItem;

                Quaternion lookAtRot = Quaternion.LookRotation(targetItem.targetDir, targetItem.transform.up);
                Vector3 resultEuler = lookAtRot.eulerAngles;

                CtrlCam.transform.DORotate(resultEuler, CamGotoTime);

                CtrlCam.transform.DOMove(targetItem.targetPos, CamGotoTime)
                    .OnPlay(() =>
                    {
                        // 发送 开始切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetBegin()
                        {
                            _targetEnum = targetItem.targetEnum,
                            _targetName = targetItem.targetName
                        });
                        IsCanControlCam = false;
                    })
                    .OnComplete(() =>
                    {
                        IsCanControlCam = true;

                        // 发送 完成切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetEnd()
                        {
                            _targetEnum = targetItem.targetEnum,
                            _targetName = targetItem.targetName
                        });
                    });

                CurTarget = newTarget;

                this.SendEvent(new Event_SwitchToFollowTarget()
                {
                    _followTargetItem = newTarget as HK_FollowTargetItem,
                    _moveSpeed = moveSpeed,
                    _wheelSpeed = wheelSpeed
                });

                CamMoveType.Value = MoveType.Follow;
            }
        }

        public void SetCameraState(bool isCanCtrl)
        {
            if (isCanCtrl)
                CtrlCam.enabled = true;
            else
                CtrlCam.enabled = false;
        }
    }
}